package com.kandinfo.base.common.service;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;

import com.kandinfo.base.common.dto.widget.DataTablesRequestDto;
import com.kandinfo.base.common.repository.BaseRepository;

/**
 * 基础service 类
 * @author wenchongyang
 *
 * @param <T>
 * @param <ID>
 * @param <R>
 */
public abstract class AbstractService<T, ID extends Serializable, R extends BaseRepository<T, ID>> {
    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
    protected R repository;

    public void setRepository(R repository) {
        this.repository = repository;
    }

    public Page<T> findAll(Pageable pageable) {
        return repository.findAll(pageable);
    }

    public T save(T entity) {
        return repository.save(entity);
    }

    public T findOne(ID id) {
        return repository.findOne(id);
    }

    public boolean exists(ID id) {
        return repository.exists(id);
    }

    public long count() {
        return repository.count();
    }

    public void delete(ID id) {
        repository.delete(id);
    }

    public void delete(T entity) {
        repository.delete(entity);
    }

    public void delete(Iterable<? extends T> entities) {
        repository.delete(entities);
    }

    public void deleteAll() {
        repository.deleteAll();
    }

    public T findOne(Specification<T> spec) {
        return repository.findOne(spec);
    }

    public List<T> findAll(Specification<T> spec) {
        return repository.findAll(spec);
    }

    public Page<T> findAll(Specification<T> spec, Pageable pageable) {
        return repository.findAll(spec, pageable);
    }

    public List<T> findAll(Specification<T> spec, Sort sort) {
        return repository.findAll(spec, sort);
    }

    public long count(Specification<T> spec) {
        return repository.count(spec);
    }

    public List<T> findAll() {
        return repository.findAll();
    }

    public List<T> findAll(Sort sort) {
        return repository.findAll(sort);
    }

    public List<T> findAll(Iterable<ID> ids) {
        return repository.findAll(ids);
    }

    public List<T> save(Iterable<T> entities) {
        return repository.save(entities);
    }

    public void flush() {
        repository.flush();
    }

    public T saveAndFlush(T entity) {
        return repository.saveAndFlush(entity);
    }

    public void deleteInBatch(Iterable<T> entities) {
        repository.deleteInBatch(entities);
    }

    public void deleteAllInBatch() {
        repository.deleteAllInBatch();
    }

    public T getOne(ID id) {
        return repository.getOne(id);
    }

    public Pageable buildPageRequest(DataTablesRequestDto requestDto) {
        Sort sort = null;
        List<Integer> sortedColumns = requestDto.getSortedColumns();
        List<String> sortDirections = requestDto.getSortDirections();
        List<String> dataProps = requestDto.getDataProps();

        if (sortedColumns != null) {
            for (Integer item : sortedColumns) {
                String sortColumn = dataProps.get(item);
                int indexOf = 0;
                if (StringUtils.isNotBlank(sortColumn) && sortColumn.endsWith(".text")) {
                    indexOf = sortColumn.lastIndexOf(".text");
                }
                if (indexOf > 0) {
                    sortColumn = sortColumn.substring(0, indexOf);
                }
                String sortDir = sortDirections.get(0);
                sort = new Sort(Direction.fromString(sortDir), sortColumn);
            }
        } else {
            sort = new Sort(Direction.ASC, "id");
        }
        PageRequest page = new PageRequest(requestDto.getDisplayStart() / requestDto.getDisplayLength(),
                requestDto.getDisplayLength(), sort);
        return page;

    }

}
